#ifndef xpack_gc_private_gc_tuple
#define xpack_gc_private_gc_tuple
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::gc_private_gc_tuple::inc
#include"define/base_type.hpp"
#include"gc/self_management.hpp"
#include"macro/xdebug.hpp"
#include"macro/xexport.hpp"
#include"macro/xmodify.hpp"
#include"meta/is_based_on.hpp"
#include"meta/remove_const.hpp"
#include"meta/remove_membership.hpp"
#include"meta/remove_ref.hpp"
#include"meta_seq/tin.hpp"
#include"meta_seq/tlist.hpp"
#include"meta_seq/vlist.hpp"
#pragma pop_macro("xuser")

namespace mixc::gc_private_gc_tuple{
    using namespace inc;

    template<class root_t>
    struct gc_tuple{
        using base_list             = typename root_t::base_list;
        using member_list_partial   = typename root_t::member_list_partial;
        
        template<class guide_t>
        uxx routing(){
            uxx can_arrive_root     = false;
            can_arrive_root        |= routing_base<guide_t>(base_list());
            can_arrive_root        |= routing_self<guide_t>(member_list_partial());
            return can_arrive_root;
        }

    private:
        template<class guide_t>
        uxx routing_base(tlist<>){
            return false;
        }

        template<class guide_t, class ... basex_t>
        uxx routing_base(tlist<basex_t...>){
            return ((... |/*使用按位或避免跳过后续的操作*/ routing_base_core<guide_t>(tlist<basex_t>())));
        }

        template<class guide_t, class base0_t>
        uxx routing_base_core(tlist<base0_t>){
            auto child           = (root_t *)this;
            auto base            = (base0_t *)child; // 里氏转换
            auto new_gc_tuple    = (gc_tuple<base0_t> *)base;
            auto can_arrive_root = new_gc_tuple->template routing<guide_t>();
            return can_arrive_root;
        }

        template<class guide_t>
        uxx routing_base_core(tlist<>){
            return false;
        }

        template<class guide_t>
        uxx routing_self(vlist<>){
            return false;
        }

        template<class guide_t, auto ... args_v>
        uxx routing_self(vlist<args_v...>){
            return ((... |/*使用按位或避免跳过后续的操作*/ (routing_self_core<guide_t>(vlist<args_v>()))));
        }

        template<class guide_t, auto a0_v>
        uxx routing_self_core(vlist<a0_v>){
            using origin                = remove_membership<decltype(a0_v)>;

            if constexpr (tin<guide_t, origin>){
                auto field              = xmodify(((root_t *)this)->*a0_v);

                if constexpr (is_based_on<self_management, origin>){
                    return field->template routing<guide_t>();
                }
                else{
                    auto entry          = (gc_tuple<origin> *)field;
                    return entry->template routing<guide_t>();
                }
            }
            return false;
        }

        template<class guide_t>
        uxx routing_self_core(vlist<>){
            return false;
        }
    };

    template<>
    struct gc_tuple<void>{
        template<class guide_t, class array>
        static uxx routing(array & list, uxx length){
            using item_t = remove_const<
                remove_ref<decltype(list[0])>
            >;
            using gc_tuplep = gc_tuple<item_t> *;

            uxx can_arrive_root = false;

            if constexpr (is_based_on<self_management, item_t>){
                for(uxx i = 0; i < length; i++){
                    can_arrive_root |= list[i].template routing<guide_t>();
                }
            }
            else{
                for(uxx i = 0; i < length; i++){
                    can_arrive_root |= gc_tuplep(xmodify(list[i]))->template routing<guide_t>();
                }
            }
            return can_arrive_root;
        }
    };
}

#endif

xexport(mixc::gc_private_gc_tuple::gc_tuple)